﻿using HalconDotNet;
using NDK.Module.BLL;
using NDK.Motion.BLL;
using NDK.Motion.MachineManager;
using NDK.Motion.MachineResources;
using NDK.Motion.Monitor;
using NDK.Motion.StationLogic;
using NDK.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
using static NDK.Module.Model.Common;

namespace NDK.Module.StationLogic
{
    [Monitor(Description = "中转平台工位")]
    public class TransitPlatform : StationLogicBase
    {
        #region 通用
        //记录当前步骤，用于步骤变化的比较
        private StationStep _curStep = StationStep.WaitMacInit;
        //对外提供工位的步骤变化事件
        public override event PropertyChangedEventHandler PropertyChanged;
        //对外提供唯一实例
        public static TransitPlatform Instance = new TransitPlatform();
        //私有化的构造函数
        private TransitPlatform() : base()
        {
            Name = "中转平台";
        }
        //步骤字段、属性
        private StationStep _step = StationStep.WaitMacInit;
        [Monitor(Description = "当前步骤")]
        public StationStep Step
        {
            get
            {
                return _step;
            }
            set
            {
                if (_curStep != value)
                {
                    _step = value;
                    _curStep = value;
                    FileUtils.WriteLogToTxt($"{Step.ToString()}  CT:{Math.Round((double)swStepTime.ElapsedMilliseconds / 1000, 3)}s", logFold, logBaseInfo, isWriteLog);
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(value.ToString()));
                    swStepTime.Restart();
                }
            }
        }
        #endregion

        #region 变量
        public bool 告知量测1接料完成 { get; set; }
        public bool 告知量测2接料完成 { get; set; }
        public bool 告知PPG放料完成 { get; set; }
        public bool 告知量测1GRR物料放料完成 { get; set; }
        public bool 告知量测2GRR物料放料完成 { get; set; }
        private string LocalPostion { get; set; }
        #endregion

        /// <summary>
        /// 工站初始化
        /// </summary>
        public override void Init()
        {
            base.Init();
            Step = StationStep.WaitMacInit;
            logBaseInfo = "中转平台";

            ListVacuum = new List<OutputSetting>() { Machine.DicOutputIO["上料真空吸"] };
            ListCylinder = new List<ICylinder>() { Machine.DicDriveCylinder["上料气缸"] };
            SNCode1 = string.Empty;
            LocalGRRCount = 0;
            告知量测1接料完成 = false;
            告知量测2接料完成 = false;
            告知PPG放料完成 = false;
            告知量测1GRR物料放料完成 = false;
            告知量测2GRR物料放料完成 = false;
        }

        /// <summary>
        /// 工站动作流程
        /// </summary>
        /// <param name="mode"></param>
        public override void ActionProcess()
        {
            try
            {
                switch (Step)
                {
                    case StationStep.WaitMacInit:

                        Step = StationStep.Start;
                        break;
                    case StationStep.Start:
                        if (PublicMethod.OffVacuum(ListVacuum) && PublicMethod.HomeCylinder(ListCylinder) && MotionControl.AxesMove(Machine.DicPos[Name]["接料位"]))
                        {
                            Step = StationStep.等待量测允许接料;
                        }
                        break;
                    case StationStep.等待量测允许接料:
                        if (Measure1.Instance.告知中转平台允许到接料位)
                        {
                            if (PublicMethod.WorkCylinder(ListCylinder) && PublicMethod.OffVacuum(Measure1.Instance.ListVacuum, false) && PublicMethod.OpenVacuum(ListVacuum))
                            {
                                SNCode1 = Measure1.Instance.SNCode1;
                                Measure1.Instance.告知中转平台允许到接料位 = false;
                                Step = StationStep.接料完成;
                            }
                        }
                        if (Measure2.Instance.告知中转平台允许到接料位)
                        {
                            if (PublicMethod.WorkCylinder(ListCylinder) && PublicMethod.OffVacuum(Measure2.Instance.ListVacuum, false) && PublicMethod.OpenVacuum(ListVacuum))
                            {
                                SNCode1 = Measure2.Instance.SNCode1;
                                Measure2.Instance.告知中转平台允许到接料位 = false;
                                Step = StationStep.接料完成;
                            }
                        }
                        break;
                    case StationStep.接料完成:
                        if (PublicMethod.HomeCylinder(ListCylinder))
                        {
                            LocalPostion = Machine.DicLocalData[SNCode1].Position;
                            if (LocalPostion == "2" || LocalPostion == "3")
                                告知量测1接料完成 = true;
                            else
                                告知量测2接料完成 = true;
                            Step = StationStep.移动到下激光起始位;
                        }
                        break;
                    case StationStep.移动到下激光起始位:
                        if (MotionControl.AxesMove(Machine.DicPos[Name]["下激光起始位"]))
                        {
                            if (StationManager.MachineProductionMode != RunningModeEnum.EmptyMode)
                                Machine.DicLaser["下激光1"].Start();
                            Step = StationStep.移动到下激光终点位;
                        }
                        break;
                    case StationStep.移动到下激光终点位:
                        if (MotionControl.AxesMove(Machine.DicPos[Name]["下激光终止位"]))
                        {
                            Step = StationStep.移动到下激光起始位1;
                        }
                        break;
                    case StationStep.移动到下激光起始位1:
                        if (MotionControl.AxesMove(Machine.DicPos[Name]["下激光起始位1"]))
                        {
                            if (StationManager.MachineProductionMode != RunningModeEnum.EmptyMode)
                            {
                                Machine.DicLaser["下激光2"].Start();
                            }
                            Step = StationStep.移动到下激光终点位1;
                        }
                        break;
                    case StationStep.移动到下激光终点位1:
                        if (MotionControl.AxesMove(Machine.DicPos[Name]["下激光终止位1"]))
                        {
                            if (StationManager.MachineProductionMode != RunningModeEnum.EmptyMode)
                            {
                                Machine.DicLocalData[SNCode1].DownLaser1 = Machine.DicLaser["下激光1"].HeightImage(2000);
                                Machine.DicLocalData[SNCode1].DownLaser2 = Machine.DicLaser["下激光1"].LuminanceImage(2000);
                                Machine.DicLocalData[SNCode1].MidLaser1 = Machine.DicLaser["下激光2"].HeightImage(2000);

                                if (GetImageStatus(new List<string>() { "下激光1", "下激光1", "下激光2" }, new List<HImage>() { Machine.DicLocalData[SNCode1].DownLaser1,
                                    Machine.DicLocalData[SNCode1].DownLaser2,Machine.DicLocalData[SNCode1].MidLaser1 }, Step) != StationStep.End)
                                {
                                    Step = StationStep.移动到下激光起始位;
                                    break;
                                }

                                EventVisoion.OnTransMoverLaserRefresh(new EventVisoion.ImageRefreshEventArgs()
                                {
                                    SN = SNCode1
                                });
                            }
                            Step = StationStep.移动到放料等待位;
                        }
                        break;
                    case StationStep.移动到放料等待位:
                        if (!PPG.Instance.告知中转平台允许放料)
                            if (!MotionControl.AxesMove(Machine.DicPos[Name]["出料等待位"]))
                                break;
                        Step = StationStep.等待PPG允许放料;
                        break;
                    case StationStep.等待PPG允许放料:
                        if (PPG.Instance.告知中转平台允许放料)
                        {
                            if (MotionControl.AxesMove(Machine.DicPos[Name]["出料位"]))
                            {
                                if (PublicMethod.WorkCylinder(ListCylinder) && PublicMethod.OffVacuum(ListVacuum, false) && PublicMethod.OpenVacuum(PPG.Instance.ListVacuum))
                                {
                                    PPG.Instance.告知中转平台允许放料 = false;
                                    Step = StationStep.放料完成;
                                }
                            }
                        }
                        break;
                    case StationStep.放料完成:
                        if (PublicMethod.HomeCylinder(ListCylinder))
                        {
                            PublicMethod.OffVacuum(ListVacuum);
                            告知PPG放料完成 = true;
                            Step = StationStep.GRR模式判断;
                        }
                        break;
                    case StationStep.GRR模式判断:
                        if (StationManager.MachineProductionMode == RunningModeEnum.GRRMode)
                        {
                            LocalGRRCount++;
                            if (LocalGRRCount == GRR循环次数)
                            {
                                LocalGRRCount = 0;
                            }
                            else
                            {
                                Step = StationStep.等待GRR物料归回;
                                break;
                            }
                        }
                        Step = StationStep.End;
                        break;
                    case StationStep.等待GRR物料归回:
                        if (PPG.Instance.告知中转GRR物料放料完成)
                        {
                            PPG.Instance.告知中转GRR物料放料完成 = false;
                            Step = StationStep.GRR物料到量测放料;
                        }
                        break;
                    case StationStep.GRR物料到量测放料:
                        if (MotionControl.AxesMove(Machine.DicPos[Name]["接料位"]))
                        {
                            if (LocalPostion == "2" || LocalPostion == "3")
                            {
                                if (PublicMethod.WorkCylinder(ListCylinder) && PublicMethod.OpenVacuum(Measure1.Instance.ListVacuum) && PublicMethod.OffVacuum(ListVacuum, false))
                                {
                                    Step = StationStep.GRR物料放料完成;
                                }
                            }
                            else
                            {
                                if (PublicMethod.WorkCylinder(ListCylinder) && PublicMethod.OpenVacuum(Measure2.Instance.ListVacuum) && PublicMethod.OffVacuum(ListVacuum, false))
                                {
                                    Step = StationStep.GRR物料放料完成;
                                }
                            }
                        }
                        break;
                    case StationStep.GRR物料放料完成:
                        Thread.Sleep(200);
                        if (PublicMethod.HomeCylinder(ListCylinder))
                        {
                            PublicMethod.OffVacuum(ListVacuum);
                            if (LocalPostion == "2" || LocalPostion == "3")
                                告知量测1GRR物料放料完成 = true;
                            else
                                告知量测2GRR物料放料完成 = true;
                            Step = StationStep.End;
                        }
                        break;
                    case StationStep.End:
                        Step = StationStep.WaitMacInit;
                        break;
                }
            }
            catch (Exception ex)
            {
                UILog_Error($"[ {logBaseInfo} ActionProcess Thread ERROR] {ex.Message}");
                if (AlarmPause(logBaseInfo, $"当前状态:{Step} 报警异常:{ex.Message}", "点击确定，再试一次；点击取消，继续运行", "再试一次", "继续运行") == DialogResult.OK)
                {

                }
            }
        }

        public override void EmptyActionProcess()
        {
            ActionProcess();
        }

        public override void GRRActionProcess()
        {
            ActionProcess();
        }

        /// <summary>
        /// 工位步骤定义
        /// </summary>
        public enum StationStep
        {
            /// <summary>
            /// 等待机台初始化
            /// </summary>
            [Description("等待机台初始化")]
            WaitMacInit,
            [Description("开始")]
            Start,
            等待量测允许接料,
            接料完成,
            移动到下激光起始位,
            移动到下激光终点位,
            移动到下激光起始位1,
            移动到下激光终点位1,
            移动到放料等待位,
            等待PPG允许放料,
            放料完成,
            GRR模式判断,
            等待GRR物料归回,
            GRR物料到量测放料,
            GRR物料放料完成,
            [Description("工站完成")]
            End,
        }

        StationStep GetImageStatus(List<string> CameraName, List<HImage> hImage, StationStep stationStep)
        {
            StationStep step = stationStep;
            for (int i = 0; i < CameraName.Count; i++)
            {
                if (hImage[i] == null)
                {
                    if (AlarmPause($"{logBaseInfo}采图异常", $"{CameraName[i]}: 采集异常：", "请检查相机是否掉线及相机参数是否存在异常", " 再次拍照", "忽略继续") == DialogResult.OK)
                    {
                        if (Line == "右")
                        {
                            //if (Machine.DicLaserIp.ContainsKey(CameraName[i]))
                            //{
                            //    Machine.DicLaser[CameraName[i]].Connect(Machine.DicLaserIp[CameraName[i]][0], Convert.ToInt32(Machine.DicLaserIp[CameraName[i]][1]));
                            //    Machine.DicLaser[CameraName[i]].Stop();
                            //}
                        }
                        return step;
                    }
                }
            }
            return StationStep.End;
        }
    }
}
